package com.cruzr.opengles.map.layer;

import android.opengl.GLES20;
import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;

public class GridLayer {

    private static final String TAG = "GridLayer";

    private static final float POINT_Z = 0.1f;
    private static float RESOLUTION = 0.005f;

    // 0xFFD6E8F9;
    public static final int INT_R_BG = 0xD6;
    public static final int INT_G_BG = 0xE8;
    public static final int INT_B_BG = 0xF9;

    public static final byte COLOR_BG = 0;
    public static final byte COLOR_WALL = -1;
    public static final byte COLOR_AREA = 1;

    public static final float SQRT_2 = (float) Math.sqrt(2);

    private FloatBuffer mPointBuffer;

    private List<Float> mPointList;

    public GridLayer() {
        mPointList = new ArrayList();
    }

    public void updateMap(int width, int height, byte[] pixels) {
        if (width <= 0 || height <= 0 || pixels == null || pixels.length == 0) {
            return;
        }
        if (width * height != pixels.length) {
            Log.i(TAG, "width * height : " + width * height
                    + ", pixels.length : " + pixels.length);
            return;
        }

        mPointList.clear();
        int centerX = width / 2;
        int centerY = height / 2;
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int index = j * width + i;
                if (pixels[index] == COLOR_AREA) {
                    float x = (i - centerX)  * RESOLUTION;
                    float y = (j - centerY) * RESOLUTION;
                    float z = POINT_Z;
                    mPointList.add(x);
                    mPointList.add(y);
                    mPointList.add(z);
                }
            }
        }

        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int index = j * width + i;
                if (pixels[index] == COLOR_WALL) {
                    float x = (i - centerX)  * RESOLUTION;
                    float y = (j - centerY) * RESOLUTION;
                    float z = 2 * POINT_Z;
                    mPointList.add(x);
                    mPointList.add(y);
                    mPointList.add(z);
                }
            }
        }
        Log.i(TAG, "PointList size : " + mPointList.size());

        updatePointBuffer();
    }

    private void updatePointBuffer() {
        float[] point = new float[mPointList.size()];
        for (int i = 0; i < mPointList.size(); i++) {
            point[i] = (float) mPointList.get(i);
        }

        ByteBuffer pointBuffer = ByteBuffer.allocateDirect(point.length * 4);// 1 float = 4 byte
        pointBuffer.order(ByteOrder.nativeOrder());
        mPointBuffer = pointBuffer.asFloatBuffer();
        mPointBuffer.put(point);
        mPointBuffer.position(0);

    }

    public void drawMap(int positionHandle, int sizeHandler, float scale) {
        if (mPointList.size() / 3 <= 1) {
            return;
        }
        Log.i(TAG, "drawMap -> scale : " + scale);

        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 0, mPointBuffer);
        GLES20.glUniform1f(sizeHandler, RESOLUTION * scale * 1080 * SQRT_2);

        GLES20.glEnableVertexAttribArray(positionHandle);
        GLES20.glDrawArrays(GLES20.GL_POINTS, 0, mPointList.size() / 3);
        GLES20.glDisableVertexAttribArray(positionHandle);
    }

}
